home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / utils / init / postinit.c < prev   
Encoding:
C/C++ Source or Header  |  1993-04-16  |  20.3 KB  |  740 lines

  1. /* ----------------------------------------------------------------
  2.  *   FILE
  3.  *    postinit.c
  4.  *    
  5.  *   DESCRIPTION
  6.  *    postgres initialization utilities
  7.  *
  8.  *   INTERFACE ROUTINES
  9.  *    InitPostgres()
  10.  *
  11.  *   NOTES
  12.  *    InitializePostgres() is the function called from PostgresMain
  13.  *    which does all non-trival initialization, mainly by calling
  14.  *    all the other initialization functions.  InitializePostgres()
  15.  *    is only used within the "postgres" backend and so that routine
  16.  *    is in tcop/postgres.c  InitPostgres() is needed in cinterface.a
  17.  *    because things like the bootstrap backend program need it. Hence
  18.  *    you find that in this file...
  19.  *
  20.  *    If you feel the need to add more initialization code, it should be
  21.  *    done in InitializePostgres() or someplace lower.  Do not start
  22.  *    putting stuff in PostgresMain - if you do then someone
  23.  *    will have to clean it up later, and it's not going to be me!
  24.  *    -cim 10/3/90
  25.  *
  26.  *   IDENTIFICATION
  27.  *    $Header: /private/postgres/src/utils/init/RCS/postinit.c,v 1.35 1992/08/03 17:42:01 mao Exp $
  28.  * ----------------------------------------------------------------
  29.  */
  30.  
  31. #include <fcntl.h>
  32. #include <stdio.h>
  33. #include <strings.h>
  34. #include <sys/file.h>
  35. #include <sys/types.h>
  36. #include <math.h>
  37.  
  38. #include "tmp/postgres.h"
  39.  
  40. #include "machine.h"        /* for BLCKSZ, for InitMyDatabaseId() */
  41.  
  42. #include "access/heapam.h"
  43. #include "access/tqual.h"
  44. #include "storage/bufpage.h"    /* for page layout, for InitMyDatabaseId() */
  45. #include "storage/sinval.h"
  46. #include "storage/sinvaladt.h"
  47. #include "storage/lmgr.h"
  48. #include "storage/bufmgr.h"
  49. #include "support/master.h"
  50.  
  51. #include "tmp/miscadmin.h"
  52. #include "tmp/portal.h"        /* for EnablePortalManager, etc. */
  53.  
  54. #include "utils/exc.h"        /* for EnableExceptionHandling, etc. */
  55. #include "utils/fmgr.h"        /* for EnableDynamicFunctionManager, etc. */
  56. #include "utils/log.h"
  57. #include "utils/mcxt.h"        /* for EnableMemoryContext, etc. */
  58.  
  59. #include "catalog/catname.h"
  60. #include "catalog/pg_database.h"
  61.  
  62. #include "tmp/miscadmin.h"
  63.  
  64. /* ----------------
  65.  *    global variables & stuff
  66.  *    XXX clean this up! -cim 10/5/90
  67.  * ----------------
  68.  */
  69.     
  70. extern bool    override;
  71. extern int    Quiet;
  72. IPCKey        PostgresIpcKey;
  73.  
  74. /*
  75.  * XXX PostgresPath and PostgresDatabase belong somewhere else.
  76.  */
  77. String    PostgresPath = NULL;
  78. String    PostgresDatabase = NULL;
  79.  
  80. extern int Debugfile, Ttyfile;
  81. extern int Portfd, Packfd, Pipefd;
  82.  
  83. extern BackendId    MyBackendId;
  84. extern BackendTag    MyBackendTag;
  85. extern NameData        MyDatabaseNameData;
  86. extern Name        MyDatabaseName;
  87.  
  88. extern bool        MyDatabaseIdIsInitialized;
  89. extern ObjectId        MyDatabaseId;
  90. extern bool        TransactionInitWasProcessed;
  91.  
  92. /* extern struct    bcommon    Ident;    No longer needed */
  93.  
  94. extern int    Debug_file, Err_file, Noversion;
  95.  
  96. extern int on_exitpg();
  97.  
  98. #ifndef    private
  99. #ifndef    EBUG
  100. #define    private    static
  101. #else    /* !defined(EBUG) */
  102. #define private
  103. #endif    /* !defined(EBUG) */
  104. #endif    /* !defined(private) */
  105.  
  106. /* ----------------------------------------------------------------
  107.  *            InitPostgres support
  108.  * ----------------------------------------------------------------
  109.  */
  110.  
  111. /* --------------------------------
  112.  *  InitMyDatabaseId() -- Find and record the OID of the database we are
  113.  *              to open.
  114.  *
  115.  *    The database's oid forms half of the unique key for the system
  116.  *    caches and lock tables.  We therefore want it initialized before
  117.  *    we open any relations, since opening relations puts things in the
  118.  *    cache.  To get around this problem, this code opens and scans the
  119.  *    pg_database relation by hand.
  120.  *
  121.  *    This algorithm relies on the fact that first attribute in the
  122.  *    pg_database relation schema is the database name.  It also knows
  123.  *    about the internal format of tuples on disk and the length of
  124.  *    the datname attribute.  It knows the location of the pg_database
  125.  *    file.
  126.  *
  127.  *    This code is called from InitDatabase(), after we chdir() to the
  128.  *    database directory but before we open any relations.
  129.  * --------------------------------
  130.  */
  131.  
  132. void
  133. InitMyDatabaseId()
  134. {
  135.     int        dbfd;
  136.     int        nbytes;
  137.     int        max, i;
  138.     HeapTuple    tup;
  139.     Page    pg;
  140.     PageHeader    ph;
  141.     Form_pg_database    tup_db;
  142.  
  143.     /* ----------------
  144.      *  If we're unable to open pg_database, we're not running in the
  145.      *  data/base/dbname directory.  This happens only when we're
  146.      *  creating the first database.  In that case, just use
  147.      *  InvalidObjectId as the dbid, since we're not using shared memory.
  148.      * ----------------
  149.      */
  150.     if ((dbfd = open("../../pg_database", O_RDONLY, 0666)) < 0) {
  151.     LockDisable(true);
  152.     return;
  153.     }
  154.  
  155.     /* ----------------
  156.      *    read and examine every page in pg_database
  157.      *
  158.      *    Raw I/O! Read those tuples the hard way! Yow!
  159.      *
  160.      *  Why don't we use the access methods or move this code
  161.      *  someplace else?  This is really pg_database schema dependent
  162.      *  code.  Perhaps it should go in lib/catalog/pg_database?
  163.      *  -cim 10/3/90
  164.      *
  165.      *  mao replies 4 apr 91:  yeah, maybe this should be moved to
  166.      *  lib/catalog.  however, we CANNOT use the access methods since
  167.      *  those use the buffer cache, which uses the relation cache, which
  168.      *  requires that the dbid be set, which is what we're trying to do
  169.      *  here.
  170.      * ----------------
  171.      */
  172.     pg = (Page) palloc(BLCKSZ);
  173.     ph = (PageHeader) pg;
  174.  
  175.     while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ) {
  176.     max = PageGetMaxOffsetIndex(pg);
  177.  
  178.     /* look at each tuple on the page */
  179.     for (i = 0; i <= max; i++) {
  180.         int offset;
  181.  
  182.         /* if it's a freed tuple, ignore it */
  183.         if (!(ph->pd_linp[i].lp_flags & LP_USED))
  184.         continue;
  185.  
  186.         /* get a pointer to the tuple itself */
  187.         offset = (int) ph->pd_linp[i].lp_off;
  188.         tup = (HeapTuple) (((char *) pg) + offset);
  189.  
  190.         /*
  191.          *  if the tuple has been deleted (the database was destroyed),
  192.          *  skip this tuple.  XXX warning, will robinson:  violation of
  193.          *  transaction semantics happens right here.  we should check
  194.          *  to be sure that the xact that deleted this tuple actually
  195.          *  committed.  only way to do this at init time is to paw over
  196.          *  the log relation by hand, too.  let's be optimistic.
  197.          *
  198.          *  XXX This is an evil type cast.  tup->t_xmax is char[5] while
  199.          *  TransactionId is struct * { char data[5] }.  It works but
  200.          *  if data is ever moved and no longer the first field this 
  201.          *  will be broken!! -mer 11 Nov 1991.
  202.          */
  203.         if (TransactionIdIsValid((TransactionId)tup->t_xmax))
  204.         continue;
  205.  
  206.         /*
  207.          *  Okay, see if this is the one we want.
  208.          *    XXX 1 july 91:  mao and mer discover that tuples now squash
  209.          *            t_bits.  Why is this?
  210.          *
  211.          *     24 july 92:  mer realizes that the t_bits field is only
  212.          *                  used in the event of null values.  If no
  213.          *                  fields are null we reduce the header size
  214.          *                  by doing the squash.  t_hoff tells you exactly
  215.          *                  how big the header actually is. use the PC
  216.          *                  means of getting at sys cat attrs.
  217.          */
  218.         tup_db = (Form_pg_database)GETSTRUCT(tup);
  219.  
  220.         /* note: MyDatabaseName set by call to SetDatabaseName() */
  221.         if (strncmp(&(MyDatabaseName->data[0]),
  222.             &(tup_db->datname.data[0]),
  223.             16) == 0)
  224.         {
  225.         MyDatabaseId = tup->t_oid;
  226.         goto done;
  227.         }
  228.     }
  229.     }
  230.     
  231. done:
  232.     (void) close(dbfd);
  233.     pfree(pg);
  234.  
  235.     if (!ObjectIdIsValid(MyDatabaseId))
  236.     elog(FATAL,
  237.          "Database %s does not exist in %s",
  238.          MyDatabaseName,
  239.          &DatabaseRelationName->data[0]);
  240. }
  241.  
  242. /* ----------------
  243.  *    DoChdirAndInitDatabaseNameAndPath
  244.  *
  245.  *    this just chdir's to the proper data/base directory
  246.  *    XXX clean this up more.
  247.  *
  248.  * XXX The following code is an incorrect of the semantics
  249.  * XXX described in the header file.  Handling of defaults
  250.  * XXX should happen here, too.
  251.  * ----------------
  252.  */
  253. void
  254. DoChdirAndInitDatabaseNameAndPath(name, path)
  255.     String    name;        /* name of database */
  256.     String    path;        /* full path to database */
  257. {
  258.     /* ----------------
  259.      *    sanity check (database may not change once set)
  260.      * ----------------
  261.      */
  262.     AssertState(!StringIsValid(GetDatabasePath()));
  263.     AssertState(!StringIsValid(GetDatabaseName()));
  264.  
  265.     /* ----------------
  266.      *    check the path
  267.      * ----------------
  268.      */
  269.     if (StringIsValid(path))
  270.     SetDatabasePath(path);
  271.     else
  272.     elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: path:%s is not valid",
  273.          path);
  274.  
  275.     /* ----------------
  276.      *    check the name
  277.      * ----------------
  278.      */
  279.     if (StringIsValid(name))
  280.     SetDatabaseName(name);
  281.     else 
  282.     elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: name:%s is not valid",
  283.          name);
  284.  
  285.     /* ----------------
  286.      *    change to the directory, or die trying.
  287.      * ----------------
  288.      */
  289.     if (*path && chdir(path) < 0)
  290.     elog(FATAL, "DoChdirAndInitDatabaseNameAndPath: chdir(\"%s\"): %m",
  291.          path);
  292. }
  293.  
  294. /* --------------------------------
  295.  *    InitUserid
  296.  *
  297.  *    initializes crap associated with the user id.
  298.  * --------------------------------
  299.  */
  300. void
  301. InitUserid() {
  302.     setuid(geteuid());
  303.     SetUserId();
  304. }
  305.  
  306. /* --------------------------------
  307.  *    InitCommunication
  308.  *
  309.  *    This routine initializes stuff needed for ipc, locking, etc.
  310.  *    it should be called something more informative.
  311.  *
  312.  * Note:
  313.  *    This does not set MyBackendId.  MyBackendTag is set, however.
  314.  * --------------------------------
  315.  */
  316.  
  317. void
  318. InitCommunication()
  319. {
  320.     String    getenv();    /* XXX style */
  321.     String    postid;
  322.     String    postport;
  323.     IPCKey    key;
  324.  
  325.     /* ----------------
  326.      *    try and get the backend tag from POSTID
  327.      * ----------------
  328.      */
  329.     MyBackendId = -1;
  330.  
  331.     postid = getenv("POSTID");
  332.     if (!PointerIsValid(postid)) {
  333.     MyBackendTag = -1;
  334.     } else {
  335.     MyBackendTag = atoi(postid);
  336.     Assert(MyBackendTag >= 0);
  337.     }
  338.  
  339.     /* ----------------
  340.      *  try and get the ipc key from POSTPORT
  341.      * ----------------
  342.      */
  343.     postport = getenv("POSTPORT");
  344.     
  345.     if (PointerIsValid(postport)) {
  346.     SystemPortAddress address = atoi(postport);
  347.  
  348.     if (address == 0)
  349.         elog(FATAL, "InitCommunication: invalid POSTPORT");
  350.  
  351.     if (MyBackendTag == -1)
  352.         elog(FATAL, "InitCommunication: missing POSTID");
  353.  
  354.     key = SystemPortAddressCreateIPCKey(address);
  355.  
  356. /*
  357.  * Enable this if you are trying to force the backend to run as if it is
  358.  * running under the postmaster.
  359.  *
  360.  * This goto forces Postgres to attach to shared memory instead of using
  361.  * malloc'ed memory (which is the normal behavior if run directly).
  362.  *
  363.  * To enable emulation, run the following shell commands (in addition
  364.  * to enabling this goto)
  365.  *
  366.  *     % setenv POSTID 1
  367.  *     % setenv POSTPORT 4321
  368.  *     % postmaster &
  369.  *     % kill -9 %1
  370.  *
  371.  * Upon doing this, Postmaster will have allocated the shared memory resources
  372.  * that Postgres will attach to if you enable EMULATE_UNDER_POSTMASTER.
  373.  *
  374.  * This comment may well age with time - it is current as of 8 January 1990
  375.  * 
  376.  * Greg
  377.  */
  378.  
  379. #ifdef EMULATE_UNDER_POSTMASTER
  380.  
  381.     goto forcesharedmemory;
  382.  
  383. #endif
  384.  
  385.     } else if (IsUnderPostmaster) {
  386.     elog(FATAL,
  387.          "InitCommunication: under postmaster and POSTPORT not set");
  388.     } else {
  389.     /* ----------------
  390.      *  assume we're running a postgres backend by itself with
  391.      *  no front end or postmaster.
  392.      * ----------------
  393.      */
  394.     if (MyBackendTag == -1) {
  395.         MyBackendTag = 1;
  396.     }
  397.  
  398.     key = PrivateIPCKey;
  399.     }
  400.  
  401.     /* ----------------
  402.      *  initialize shared memory and semaphores appropriately.
  403.      * ----------------
  404.      */
  405. #ifdef EMULATE_UNDER_POSTMASTER
  406.  
  407. forcesharedmemory:
  408.  
  409. #endif
  410.  
  411.     PostgresIpcKey = key;
  412.     AttachSharedMemoryAndSemaphores(key);
  413. }
  414.  
  415.  
  416. /* --------------------------------
  417.  *    InitStdio
  418.  *
  419.  *    this routine consists of a bunch of code fragments
  420.  *    that used to be randomly scattered through cinit().
  421.  *    they all seem to do stuff associated with io.
  422.  * --------------------------------
  423.  */
  424. void
  425. InitStdio()
  426. {
  427.     /* ----------------
  428.      *    this appears to be a funky variable used with the IN and OUT
  429.      *  macros for controlling the error message indent level.
  430.      * ----------------
  431.      */
  432.     ElogDebugIndentLevel = 0;
  433.  
  434.     /* ----------------
  435.      *    old socket initialization crud starts here
  436.      * ----------------
  437.      */
  438.     Ttyfile = 0;
  439.     Debugfile = Debug_file = DebugFileOpen();
  440.  
  441.     if (IsUnderPostmaster) {
  442.     struct    dpacket    pack;
  443.         
  444.     /* ----------------
  445.      *    why the hell are we doing this here???  -cim 
  446.      * ----------------
  447.      */
  448.     if (!ValidPgVersion(".") || !ValidPgVersion("../.."))
  449.     {
  450.         extern char *DBName;
  451.         elog(NOTICE, "InitStdio: !ValidPgVersion");
  452.         if (strcmp(DBName, "template1"))
  453.             elog(FATAL, "Did you run createdb on %s yet??", DBName);
  454.         else
  455.             elog(FATAL, "Did you run initdb yet??");
  456.     }
  457.     }
  458.  
  459.     Err_file = ErrorFileOpen();
  460. }
  461.  
  462. /* --------------------------------
  463.  *    InitPostgres
  464.  *
  465.  * Note:
  466.  *    Be very careful with the order of calls in the InitPostgres function.
  467.  * --------------------------------
  468.  */
  469. bool    PostgresIsInitialized = false;
  470. extern int NBuffers;
  471.  
  472. /*
  473.  *  this global is used by wei for testing his code, but must be declared
  474.  *  here rather than in postgres.c so that it's defined for cinterface.a
  475.  *  applications.
  476.  */
  477.  
  478. int    testFlag = 0;
  479. int    lockingOff = 0;
  480.  
  481. /*
  482.  */
  483. void
  484. InitPostgres(name)
  485.     String    name;        /* database name */
  486. {
  487.     bool    bootstrap;    /* true if BootstrapProcessing */
  488.     extern    DestroyLocalRelList();
  489.  
  490.     /* ----------------
  491.      *    see if we're running in BootstrapProcessing mode
  492.      * ----------------
  493.      */
  494.     bootstrap = IsBootstrapProcessingMode();
  495.     
  496.     /* ----------------
  497.      *    turn on the exception handler.  Note: we cannot use elog, Assert,
  498.      *  AssertState, etc. until after exception handling is on.
  499.      * ----------------
  500.      */
  501.     EnableExceptionHandling(true);
  502.  
  503.     /* ----------------
  504.      *    A stupid check to make sure we don't call this more than once.
  505.      *  But things like ReinitPostgres() get around this by just diddling
  506.      *    the PostgresIsInitialized flag.
  507.      * ----------------
  508.      */
  509.     AssertState(!PostgresIsInitialized);
  510.  
  511.     /* ----------------
  512.      *    EnableTrace is poorly understood by the current postgres
  513.      *  implementation people.  Since none of us know how it really
  514.      *  is intended to function, we keep it turned off for now.
  515.      *  Turning it on will cause a core dump in all the non-sequent
  516.      *  ports.  Actually it may fail there too.  Who knows. -cim 10/3/90
  517.      * ----------------
  518.      */
  519.     EnableTrace(false);
  520.  
  521.     /* ----------------
  522.      *    Memory system initialization.
  523.      *  (we may call palloc after EnableMemoryContext())
  524.      *
  525.      *  Note EnableMemoryContext() must happen before EnablePortalManager().
  526.      * ----------------
  527.      */
  528.     EnableMemoryContext(true);    /* initializes the "top context" */
  529.     EnablePortalManager(true);    /* memory for portal/transaction stuff */
  530.  
  531.     /* ----------------
  532.      *    initialize the backend local portal stack used by
  533.      *  internal PQ function calls.  see src/lib/libpq/be-dumpdata.c
  534.      *  This is different from the "portal manager" so this goes here.
  535.      *  -cim 2/12/91
  536.      * ----------------
  537.      */    
  538.     be_portalinit();
  539.  
  540.     /* ----------------
  541.      *     attach to shared memory and semaphores, and initialize our
  542.      *   input/output/debugging file descriptors.
  543.      * ----------------
  544.      */
  545.     InitCommunication();
  546.     InitStdio();
  547.  
  548.     if (!TransactionFlushEnabled())
  549.         on_exitpg(FlushBufferPool, (caddr_t) 0);
  550.  
  551.     /* ----------------
  552.      *    check for valid "meta gunk" (??? -cim 10/5/90) and change to
  553.      *  database directory.
  554.      *
  555.      *  Note:  DatabaseName, MyDatabaseName, and DatabasePath are all
  556.      *  initialized with DatabaseMetaGunkIsConsistent(), strncpy() and
  557.      *  DoChdirAndInitDatabase() below!  XXX clean this crap up!
  558.      *  -cim 10/5/90
  559.      * ----------------
  560.      */
  561.     {
  562.     static char  myPath[MAXPGPATH];    /* DatabasePath points here! */
  563.     static char  myName[17];     /* DatabaseName points here! */
  564.  
  565.     /* ----------------
  566.      *  DatabaseMetaGunkIsConsistent fills in myPath, but what about
  567.      *  when bootstrap or Noversion is true?? -cim 10/5/90
  568.      * ----------------
  569.      */
  570.     myPath[0] = '\0';
  571.     
  572.     if (! bootstrap)
  573.         if (! DatabaseMetaGunkIsConsistent(name, myPath))
  574.         if (! Noversion)
  575.             elog(FATAL,
  576.              "InitPostgres: ! DatabaseMetaGunkIsConsistent");
  577.     
  578.     (void) strncpy(myName, name, sizeof(myName));
  579.  
  580.     /* ----------------
  581.      *  ok, we've figured out myName and myPath, now save these
  582.      *  and chdir to myPath.
  583.      * ----------------
  584.      */
  585.     DoChdirAndInitDatabaseNameAndPath(myName, myPath);
  586.     }
  587.     
  588.     /* ********************************
  589.      *    code after this point assumes we are in the proper directory!
  590.      * ********************************
  591.      */
  592.     
  593.     /* ----------------
  594.      *    initialize the database id used for system caches and lock tables
  595.      * ----------------
  596.      */
  597.     InitMyDatabaseId();
  598.  
  599.     smgrinit();
  600.  
  601.     /* ----------------
  602.      *    initialize the transaction system and the relation descriptor
  603.      *  cache.  Note we have to make certain the lock manager is off while
  604.      *  we do this.
  605.      * ----------------
  606.      */
  607.     AmiTransactionOverride(IsBootstrapProcessingMode());
  608.     LockDisable(true);
  609.  
  610.     /*
  611.      * Part of the initialization processing done here sets a read
  612.      * lock on pg_log.  Since locking is disabled the set doesn't have
  613.      * intended effect of locking out writers, but this is ok, since
  614.      * we only lock it to examine AMI transaction status, and this is
  615.      * never written after initdb is done. -mer 15 June 1992
  616.      */
  617.     RelationInitialize();       /* pre-allocated reldescs created here */
  618.     InitializeTransactionSystem(); /* pg_log,etc init/crash recovery here */
  619.     
  620.     LockDisable(false);
  621.  
  622.     /* ----------------
  623.      *    anyone knows what this does?  something having to do with
  624.      *  system catalog cache invalidation in the case of multiple
  625.      *  backends, I think -cim 10/3/90
  626.      *  Sets up MyBackendId a unique backend identifier.
  627.      * ----------------
  628.      */
  629.     InitSharedInvalidationState();
  630.  
  631.     /* ----------------
  632.      * Set up a per backend process in shared memory.  Must be done after
  633.      * InitSharedInvalidationState() as it relies on MyBackendId being
  634.      * initialized already.  XXX -mer 11 Aug 1991
  635.      * ----------------
  636.      */
  637.     InitProcess(PostgresIpcKey);
  638.  
  639.     if (MyBackendId > MaxBackendId || MyBackendId <= 0) {
  640.     elog(FATAL, "cinit2: bad backend id %d (%d)",
  641.          MyBackendTag,
  642.          MyBackendId);
  643.     }
  644.  
  645.     /* ----------------
  646.      *  initialize the access methods and set the heap-randomization
  647.      *  behaviour  (if POSTGROWS is set  then we disable the usual
  648.      *  random-search for a free page when we do an insertion).
  649.      * ----------------
  650.      */
  651.     initam();
  652.     InitRandom();        /* XXX move this to initam() */
  653.  
  654.     /* ----------------
  655.      *    initialize all the system catalog caches.
  656.      * ----------------
  657.      */
  658.     zerocaches();
  659.     InitCatalogCache();
  660.  
  661.     /* ----------------
  662.      *   set ourselves to the proper user id and figure out our postgres
  663.      *   user id.  If we ever add security so that we check for valid
  664.      *   postgres users, we might do it here.
  665.      * ----------------
  666.      */
  667.     InitUserid();
  668.  
  669.     /* ----------------
  670.      *    ok, all done, now let's make sure we don't do it again.
  671.      * ----------------
  672.      */
  673.     PostgresIsInitialized = true;
  674.     on_exitpg(DestroyLocalRelList, NULL);
  675.  
  676.     /* ----------------
  677.      *  Done with "InitPostgres", now change to NormalProcessing unless
  678.      *  we're in BootstrapProcessing mode.
  679.      * ----------------
  680.      */
  681.     if (!bootstrap)
  682.     SetProcessingMode(NormalProcessing);
  683.     if (testFlag || lockingOff)
  684.     LockDisable(true);
  685. }
  686.  
  687. /* --------------------------------
  688.  *    ReinitPostgres
  689.  *
  690.  *    It is not clear how this routine is supposed to work, or under
  691.  *    what circumstances it should be called.  But hirohama wrote it
  692.  *    for some reason so it's still here.  -cim 10/3/90
  693.  * --------------------------------
  694.  */
  695. void
  696. ReinitPostgres()
  697. {
  698.     /* assumes exception handling initialized at least once before */
  699.     AssertState(PostgresIsInitialized);
  700.  
  701.     /* reset all modules */
  702.  
  703.     EnablePortalManager(false);
  704.     EnableMemoryContext(false);
  705.  
  706.     EnableExceptionHandling(false);
  707.     EnableTrace(false);
  708.  
  709.     /* now reinitialize */
  710.     PostgresIsInitialized = false;    /* does it matter where this goes? */
  711.     InitPostgres(NULL);    
  712. }
  713.  
  714.  
  715. /* ----------------------------------------------------------------
  716.  *        traps to catch calls to obsolete routines
  717.  * ----------------------------------------------------------------
  718.  */
  719. /* ----------------
  720.  *    cinit
  721.  * ----------------
  722.  */
  723. bool
  724. cinit()
  725. {
  726.     fprintf(stderr, "cinit called! eliminate this!!\n");
  727.     AbortPostgres();
  728. }
  729.  
  730. /* ----------------
  731.  *    cinit2
  732.  * ----------------
  733.  */
  734. bool
  735. cinit2()
  736. {
  737.     fprintf(stderr, "cinit2 called! eliminate this!!\n");
  738.     AbortPostgres();
  739. }
  740.